import {_decorator, Animation, Component, EventMouse, Input, input, Vec3} from 'cc';
import {EventManager} from "db://assets/scripts/common/EventManager";
import {EventType} from "db://assets/scripts/common/EventType";

const {ccclass, property} = _decorator;

@ccclass('PlayerController')
export class PlayerController extends Component {
    /**
     * 当前位置
     */
    private currentPosition: Vec3 = new Vec3();
    /**
     * 每次跳跃过程中，当前帧移动位置差
     */
    private deltaPosition: Vec3 = new Vec3();
    /**
     * 目标位置
     */
    private targetPosition: Vec3 = new Vec3();
    /**
     * Body动画组件
     */
    @property({type: Animation, tooltip: "Body动画组件"})
    private bodyAnimation: Animation;

    /**
     * 是否正在跳
     */
    private jumping: boolean = false;
    /**
     * 跳跃步长
     */
    private jumpStep: number = 0;
    /**
     * 当前跳跃速度
     */
    private currentJumpSpeed: number = 0;
    /**
     * 当前跳跃时间
     */
    private currentJumpTime: number = 0;
    /**
     * 每次跳跃时长
     */
    private jumpTime: number = 0.3;
    /**
     * 记录总共跑了多少步
     */
    private currentJumpStep = 0;

    onEnable() {
        // 系统事件
        input.on(Input.EventType.MOUSE_UP, this.mouseUp, this);

        // 自定义事件
        EventManager.on(EventType.PLAYER_ENABLE_MOUSE_UP, this.enableMouseUp, this);
    }

    onDisable() {
        // 系统事件
        input.off(Input.EventType.MOUSE_UP, this.mouseUp, this);

        // 自定义事件
        EventManager.off(EventType.PLAYER_ENABLE_MOUSE_UP, this.enableMouseUp, this);
    }

    /**
     * 是否开启鼠标监听事件
     *
     * @param enable 是否开启鼠标监听事件
     * @link EventType#PLAYER_ENABLE_MOUSE_UP
     */
    private enableMouseUp(enable: boolean) {
        if (enable) {
            input.on(Input.EventType.MOUSE_UP, this.mouseUp, this);
        } else {
            input.off(Input.EventType.MOUSE_UP, this.mouseUp, this);
        }
    }

    start() {
        // 初始化
        this.init();
    }

    /**
     * 初始化
     */
    private init() {

    }

    /**
     * 鼠标抬起事件
     */
    private mouseUp(event: EventMouse) {
        switch (event.getButton()) {
            // 左键：跳一步
            case EventMouse.BUTTON_LEFT:
                this.jumpByStep(1);
                break;
            // 右键：跳两步
            case EventMouse.BUTTON_RIGHT:
                this.jumpByStep(2);
                break;
        }
    }

    /**
     * 根据步长跳跃
     *
     * @param step 步长
     */
    private jumpByStep(step: number) {
        // 正在跳时
        if (this.jumping) {
            // 直接返回
            return;
        }

        // 正在跳
        this.jumping = true;
        // 跳跃的步长
        this.jumpStep = step;
        // 记录一共跑了多少步
        this.currentJumpStep += step;
        // 当前跳跃的时间
        this.currentJumpTime = 0;
        // 当前跳跃的速度
        this.currentJumpSpeed = this.jumpStep / this.jumpTime;
        // 记录角色的当前位置
        this.node.getPosition(this.currentPosition);
        // 目标位置 = 当前位置 + 步长
        Vec3.add(this.targetPosition, this.currentPosition, new Vec3(this.jumpStep, 0, 0));

        // 播放动画
        switch (this.jumpStep) {
            case 1:
                this.bodyAnimation.play("one_step");
                break;
            case 2:
                this.bodyAnimation.play("two_step");
                break;
        }

        // 检测游戏是否结束
        EventManager.dispatchEvent(EventType.CHECK_GAME_IS_OVER, this.currentJumpStep);
    }

    update(deltaTime: number) {
        // 当不需要跳时
        if (!this.jumping) {
            // 直接返回
            return;
        }

        // 当前跳跃时间
        this.currentJumpTime += deltaTime;
        // 当前跳跃时间大于跳跃时间时
        if (this.currentJumpTime > this.jumpTime) {
            // 设置角色位置
            this.node.setPosition(this.targetPosition);
            // 跳跃完毕
            this.jumping = false;
        } else {
            // 记录当前角色位置
            this.node.getPosition(this.currentPosition);
            // 更新位置差的x坐标
            this.deltaPosition.x = this.currentJumpSpeed * deltaTime;
            // 更新角色位置
            Vec3.add(this.currentPosition, this.currentPosition, this.deltaPosition);
            // 更新角色位置
            this.node.setPosition(this.currentPosition);
        }
    }
}